An application program usually includes a number of separate routines. Typically, the routines include a main program and several subsidiary routines referred to as objects, modules or resources. Execution of the application program begins with the main program with calls being made to the subsidiary routines. In order to operate as a complete program, prior to execution these routines are linked together using a linker such as Microsoft Segmented Executable Linker (Link). The linker copies each of the routines into an executable (.EXE) file for the application program. The linker also provides each of the routines with information identifying the locations of other routines so that the routines can access each other. The executable file can then be executed by the computer according to the instructions in the routines.
A dynamic-link library is an executable module containing services that application programs can call to perform useful tasks. Dynamic-link libraries exist primarily to provide services to application programs. These libraries play an important role in operating systems, such as Windows and OS/2, which use them to make their services and resources available to the application programs.
Dynamic-link libraries are similar to run-time libraries, such as C-language run-time libraries. The main difference between dynamic-link libraries and run-time libraries is that dynamic-link libraries are linked with the application program at run time, not when the application program files are linked with the linker. Linking a library with an application program at run time is referred to as dynamic-linking; linking the library with an application program by using the linker is referred to as static linking.
One way to understand dynamic-link libraries is to compare them to static-link libraries. An example of a static-link library is MLIBCEW.LIB, the medium model Windows C-language run-time library. MLIBCEW.LIB contains the executable code for C-language run-time services such as strcpy, which copies character strings from one memory location to another. Such C-language run-time services are used by an application program without having to include the source code for those services. When linking a C-language compiled application program, the linker incorporates information from the appropriate static-link library. Wherever the application program uses a C-language run-time service, the linker copies that service to the application program's executable file.
The primary advantage of static-link libraries is that they make a standard set of services available to application programs, and do not require the application programs to include the original source code for those services. However, because static-link libraries are incorporated into the executable code of the application program, the static-link libraries and application programs lose their physical distinctness when linked. As a result, neither the application programs nor the static-link libraries can be updated without having to re-link the static-link libraries with the application programs.
Another problem with static-link libraries is that they are inefficient in a multitasking system such as the Windows operating system. If two application programs are running simultaneously and they use the same static-link library service, there will be two copies of that service present in the system. It would be more efficient for both application programs to share a single copy of the service, but static-link libraries provide no facility for sharing code between application programs.
With dynamic-link libraries, on the other hand, several application programs can share a single copy of a service. If two application programs are running at the same time using the Windows operating system and both use a particular service, both can share a single copy of the source code for that service.
In addition to being able to share a single copy of code, application programs using dynamic-link libraries can share other resources, such as data and hardware. For example, Windows fonts are text-drawing data that application programs can share by means of dynamic-link libraries. Likewise, Windows device drivers are dynamic-link libraries that application programs can use to share access to hardware resources.
Since a dynamic-link library is linked at run time, not with a linker, a copy of the library is not inserted into the application program's executable file. Instead, a copy of the library is loaded into memory while the application program is running. As a result, the application program and dynamic-library are always physically distinct. Such distinctness allows the application program and dynamic-link library to be updated, compiled, and tested separately from each other.
In order to access a dynamic-link library at run time, the application program must be able to obtain information indicating where to find the dynamic-link library. One method provided by the Windows operating system is to use an import library, which contains information regarding where to locate the dynamic-link library at run time. During linking, the linker uses static-link libraries and import libraries to resolve references to external services. As noted above, when an application program desires a service from a static-link library, the linker copies the code for that service into the application program's executable file. When the application program desires a service from a dynamic-link library, however, the linker does not copy any code from the dynamic-link library. Instead, the linker searches all defined import libraries to find one that contains the necessary information regarding the location of the dynamic-link library. The linker copies the necessary information from the import library to create a dynamic-link between the executing application program and dynamic-link library.
Many operating systems do not employ dynamic-link libraries. For example, the Macintosh operating system does not provide dynamic-link libraries. The Macintosh operating system does not include any import libraries or other means to provide dynamic-linking between application programs and dynamic-link library services. Some background information on the Macintosh computer system, including its operating system, may be helpful in order to understand how it differs from the Windows Operating System and OS/2.
The Macintosh computer system 10 includes a central processing unit (CPU) 12, a read-only memory (ROM) 14, a working memory 16 and an input/output (I/O) system 18 that are connected by a data bus 20, as shown in FIG. 1. The I/O system communicates with a disk storage unit 22 to pass information between the disk storage and the data bus 20. The disk storage unit can be a magnetic storage device, such as a hard disk or a floppy disk, or any other device for storing programs and data.
The working memory 16 includes a memory section known as an application heap 24 that is used to store a loaded application program 26 and other routines. The working memory includes a stack 28 that is used by the CPU 12 when executing instructions of the application program or other routines called by the application program. The stack stores local variables, and a return address of the routines currently loaded in the heap. A stack pointer (SP) 30 points to the most recent item pushed onto the stack.
The Macintosh computer system 10 includes an operating system 32 located in the ROM 14 that interfaces the application program 26 and other software to the computer system hardware. The working memory 16 includes a system heap 33 that the operating system 32 uses to store its routines. Each of the routines in the operating system is accessible to all routines, including the routines of the application program.
As shown in FIG. 1, the Macintosh operating system 32 includes a memory manager 34 that controls the location of blocks of memory in the working memory 16. The memory manager provides the application program and other routines with blocks of memory from the heap and releases memory areas that are no longer needed to the heap. Blocks of memory in the heap can be allocated and released in any order.
Each memory block allocated by the memory manager 34 is either relocatable or nonrelocatable and is accessed by an index returned by the memory manager. The index for a nonrelocatable block is a pointer that directly addresses the block. The index for a relocatable block is a handle that indirectly addresses the block. The handle points to a nonrelocatable master pointer that points to the relocatable block. If the relocatable block is moved, the contents of the master pointer are changed to reflect the new location of the segment, while the handle continues to point to the unmoved master pointer. In contrast, a nonrelocatable block never moves, so the pointer to it never changes.
One reason that the Macintosh operating system has failed to provide for dynamic-link libraries is because of the stiffly-structured working memory 16 of the Macintosh computer system 10. The Motorola MC68000 microprocessors used in early versions of the Macintosh computer system were unable to specify memory offsets greater than 32K. As a result, routines in the working memory 16, including application programs, had to be smaller than 32K bytes or had to be divided into memory segments 36 having less than 32K bytes. The microprocessors in more recent versions of the Macintosh computer system eliminated the 32K requirement, but most routines have continued to be limited to less than 32K bytes or to be divided into 32K segments in order to be compatible with the older machines. This presents a problem because the Macintosh operating system 32 allows application programs to be segmented, but other routines cannot be segmented.
The Macintosh system allows a user to create special routines known as stand-alone code that are not statically linked to any application program. A stand-alone code module exists as a single Macintosh resource that performs a service or services for an application program. A stand-alone code module is loaded and executed at run time without being divided into memory segments. Stand-alone code modules are discussed in Prouse, Macintosh Technical Notes #256: Stand-Alone Code, ad nauseam, August 1990, which is incorporated herein by reference in its entirety.
It is often necessary for a stand-alone service routine, especially one that performs services of greater than a minor complexity, to specify global variables. Global variables, in contrast to local variables, can be used by plural routines and can persist between repeated invocations of a single routine by the application program 26. This presents a problem when using the Macintosh computer system 10, because the Macintosh operating system 32 automatically provides space for global variables only for an application program 26 and not for any other routines.
When the Macintosh operating system 32 loads an application program 26 it uses runtime routines to create a structure in the application heap 24 called an A5 world 37. It is called an A5 world because the A5 register 38 of the CPU 4 holds a pointer 40 that directly or indirectly points to several important data structures used by the application program or the Macintosh operating system. The A5 register pointer 40 directly points to global variable space 42 used to store global variables that can be used by any routine.
Since a stand-alone code module is not an application program, it is not automatically provided with an A5 world of its own. As a result, a stand-alone code module normally does not use global variables of its own. This feature causes most stand-alone code modules to be limited to relatively small routines performing simple services.
Macintosh Technical Note #256, at pages 14-15, discloses source code for several routines that create a custom A5 world for a stand-alone code module. The custom A5 world allows the stand-alone code module to use global variables of its own. However, nothing in the Technical Note teaches how to use a stand-alone code module to provide the Macintosh system with the dynamic-linking capabilities provided by the Windows operating system and OS/2.
As discussed above, the Windows operating system enables dynamic-linking of dynamic-link libraries to programs by using import libraries. The Macintosh operating system does not provide any import libraries or other means to dynamically link libraries to programs. As a result, the Macintosh operating system does not share Windows' ability to efficiently share libraries without copying the service routines of the library into each program that desires the services provided by the routines.